package model;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
/**
 * The Data Acces Object for the webfarm, used with login and User crud.
 * @author Inti3D
 *
 */
public class LoginDao {

	private String sqlLoginRead   = "SELECT id, username, password FROM app.login_data where username = ? and password = ?" ;
    private String sqlLoginDelete = "DELETE FROM app.login_data where username = ?";
	private String sqlLoginCreate = "INSERT INTO app.login_data(username, password, type) VALUES(?, ?, ?)";
	private String sqlLoginUpdate = "UPDATE app.login_data SET password = ? WHERE username = ?";
	private String sqlSelectUsers = "SELECT username FROM app.login_data";
	private String sqlSelectUserbyName = "SELECT username, password, type FROM app.login_data WHERE username = ?";

	//private String sqlCreateTable = "CREATE TABLE app.login_data (id INT PRIMARY KEY, username VARCHAR(50), password VARCHAR(50))";
	
	private Connection        con      = null ;
	private PreparedStatement psRead   = null ;
	private PreparedStatement psDelete = null ;
	private PreparedStatement psCreate = null ;
	private PreparedStatement psUpdate = null ;
	private PreparedStatement psSelectUsers = null;
	private PreparedStatement psSelectUserbyName = null;
	//private PreparedStatement psCreateTable = null ;
	/**
	 * Initialize the Logindao
	 */
	public LoginDao() {
		DBmanager myDb = DBmanager.getInstance();
		con = myDb.getConnection();
		try{			
			this.psRead   = con.prepareStatement(sqlLoginRead) ;
		    this.psDelete = con.prepareStatement(sqlLoginDelete);
		    this.psCreate = con.prepareStatement(sqlLoginCreate);
		    this.psUpdate = con.prepareStatement(sqlLoginUpdate);
		    this.psSelectUsers = con.prepareStatement(sqlSelectUsers);
		    this.psSelectUserbyName = con.prepareStatement(sqlSelectUserbyName);
			
		} catch(SQLException se) {
			printSQLException(se) ;
		}
	}
	
	/**
	 * Check if the user and pass exist in the database
	 * 
	 * @param user The username that the user typed in the login.jsp
	 * @param pass The password that the user typed in the login.jsp
	 * @return an boolean if its true then the user exists
	 */
	public boolean authorize(String user, String pass) {

		try{
			MessageDigest m = null;
			try {
				m = MessageDigest.getInstance("MD5");
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			m.reset();
			m.update(pass.getBytes());
			byte[] digest = m.digest();
			BigInteger bigInt = new BigInteger(1,digest);
			String hashtext = bigInt.toString(16);
			// Now we need to zero pad it if you actually want the full 32 chars.
			while(hashtext.length() < 32 ){
			  hashtext = "0"+hashtext;
			}			
			System.out.println(hashtext);
			
			psRead.clearParameters();
			psRead.setString(1, user);
			psRead.setString(2, hashtext);
			ResultSet rs = psRead.executeQuery();
			///
			int count = 0;
			while (rs.next()) {
				return true;
			}
			rs.close();
		} catch(SQLException se) {
			printSQLException(se) ;
		}
		return false;
	}	

	/**
	 * Delete an user from the database
	 * @param username the name of the user to delete in the database
	 */
	public void deleteUser(String username) {		
		try{			
			psDelete.clearParameters() ;
		    psDelete.setString(1, username);

		    int resultaat = psDelete.executeUpdate();
		    if (resultaat == 0) { System.out.println("nix done"); }
		} catch(SQLException se) {
			printSQLException(se) ;
		}
	}

	/**
	 * Method to create an user in the database
	 * @param username The username of the new user
	 * @param password The password of the new user
	 */
	public void createUser(String username, String password) {
		try {			
			psCreate.clearParameters();
			
			psCreate.setString(1, username);
			psCreate.setString(2, password);
			psCreate.setString(3, "0");
			
			int resultaat = psCreate.executeUpdate();
			if (resultaat == 0) {
				System.out.println("nix done");
			}
		} catch (SQLException se) {
			printSQLException(se);
		}
	}

	/**
	 * Methode to change the password of the user
	 * @param username The user that needs a password change
	 * @param newPass The new password
	 */
	public void changePassword(String username, String newPass) {
		try {
			psUpdate.clearParameters();
			
			psUpdate.setString(1, newPass);
			psUpdate.setString(2, username);
					
			int resultaat = psUpdate.executeUpdate();
			if (resultaat == 0) {
				System.out.println("nix done");
			}
		} catch (SQLException se) {
			printSQLException(se);
		}
	}	
	
	
	/**
	 * Select all users
	 * @return All the users will be returned in an ResultSet
	 */
	public ResultSet selectUsers() {		
		try {
			psSelectUsers.clearParameters();
			return psSelectUsers.executeQuery();
			
		}catch(SQLException se) {
			printSQLException(se);
		}
		return null;				
	}
	
	/**
	 * Select an user by name
	 * @param name the name to select on
	 * @return The user will be returned in a ResultSet
	 */
	public ResultSet selectUserbyName(String name) {
		try {
			psSelectUserbyName.clearParameters();
			psSelectUserbyName.setString(1, name);
			
			return psSelectUserbyName.executeQuery();
		}catch (SQLException se) {
			printSQLException(se);
		}
		return null;
	}
	
	/**
	 * To print the sql exception for debug uses.
	 * @param se The SQLException
	 */
	private void printSQLException(SQLException se) {
		while(se != null) {
			System.out.print("SQLException: State:   " + se.getSQLState());
			System.out.println("Severity: " + se.getErrorCode());
			System.out.println(se.getMessage());			

			se = se.getNextException();
		}
	}	

}
